#include "clickablelabel.h"
#include <QMouseEvent>
#include <QApplication>
#include <QPainter>

ClickableLabel::ClickableLabel(QWidget* parent, Qt::WindowFlags f)
    : QLabel(parent, f),
    m_mode(Mode::Button),          // 默认按钮型
    m_selected(false),             // 初始未选中
    m_currentState(State::Default),// 初始状态为默认
    m_shape(Shape::Rectangle),
    m_defaultColor(QColor(240, 240, 240, 50)),
    m_pressedColor(QColor(197, 227, 255, 100)),
    m_hoverColor(QColor(220, 220, 220, 50)),
    m_selectedColor(QColor(160, 200, 255, 150)), // 选中状态颜色
    m_borderRadius(10),
    m_radius(50),
    m_pixmapTextSpacing(5),
    m_alignment(ContentAlignment::Left),
    m_textColor(Qt::black)
{
    setAttribute(Qt::WA_TranslucentBackground);
    setTextInteractionFlags(Qt::NoTextInteraction);
    setMouseTracking(true);  // 启用鼠标跟踪（悬浮事件依赖）
}

ClickableLabel::ClickableLabel(const QString& text, QWidget* parent, Qt::WindowFlags f)
    : QLabel(text, parent, f),
    m_mode(Mode::Button),
    m_selected(false),
    m_currentState(State::Default),
    m_shape(Shape::Rectangle),
    m_defaultColor(QColor(240, 240, 240, 50)),
    m_pressedColor(QColor(197, 227, 255, 100)),
    m_hoverColor(QColor(220, 220, 220, 50)),
    m_selectedColor(QColor(160, 200, 255, 150)),
    m_borderRadius(10),
    m_radius(50),
    m_pixmapTextSpacing(5),
    m_alignment(ContentAlignment::Left),
    m_textColor(Qt::black)
{
    setAttribute(Qt::WA_TranslucentBackground);
    setTextInteractionFlags(Qt::NoTextInteraction);
    setMouseTracking(true);
}

// 模式和选中状态接口实现
void ClickableLabel::setMode(Mode mode) {
    if (m_mode != mode) {
        m_mode = mode;
        // 切换模式时重置状态
        m_selected = false;
        m_currentState = State::Default;
        update();
    }
}

ClickableLabel::Mode ClickableLabel::getMode() const {
    return m_mode;
}

void ClickableLabel::setSelected(bool selected) {
    if (m_selected != selected) {
        m_selected = selected;

        // 三种模式都根据选中状态更新显示
        if (m_mode == Mode::Selectable || m_mode == Mode::ExclusiveSelectable) {
            m_currentState = selected ? State::Selected : State::Default;
            update();
        }

        emit selectedChanged(selected);
    }
}

bool ClickableLabel::isSelected() const {
    return m_selected;
}

void ClickableLabel::setSelectedColor(const QColor& color) {
    m_selectedColor = color;
    if (m_selected && m_mode == Mode::Selectable) {
        update();
    }
}

QColor ClickableLabel::getSelectedColor() const {
    return m_selectedColor;
}

// 四种状态的Pixmap设置
void ClickableLabel::setDefaultPixmap(const QPixmap& pixmap) {
    m_defaultPixmap = pixmap;
    // 当其他状态未设置时，修改default也需要刷新
    bool needUpdate = (m_currentState == State::Default) ||
                      (m_currentState == State::Hovered && m_hoveredPixmap.isNull()) ||
                      (m_currentState == State::Pressed && m_pressedPixmap.isNull()) ||
                      (m_currentState == State::Selected && m_selectedPixmap.isNull());

    if (needUpdate) {
        updateGeometry();
        update();
    }
}

void ClickableLabel::setHoveredPixmap(const QPixmap& pixmap) {
    m_hoveredPixmap = pixmap;
    if (m_currentState == State::Hovered) {
        updateGeometry();
        update();
    }
}

void ClickableLabel::setPressedPixmap(const QPixmap& pixmap) {
    m_pressedPixmap = pixmap;
    if (m_currentState == State::Pressed) {
        updateGeometry();
        update();
    }
}

void ClickableLabel::setSelectedPixmap(const QPixmap& pixmap) {
    m_selectedPixmap = pixmap;
    if (m_currentState == State::Selected) {
        updateGeometry();
        update();
    }
}

// 状态管理
void ClickableLabel::setCurrentState(State state) {
    // 选择型模式下，不能手动设置为非选中状态（除非取消选中）
    if (m_mode == Mode::Selectable) {
        if (m_selected && state != State::Selected && state != State::Pressed) {
            return;
        }
    }

    if (m_currentState != state) {
        m_currentState = state;
        update();
    }
}

ClickableLabel::State ClickableLabel::getCurrentState() const {
    return m_currentState;
}

// 兼容原有接口
void ClickableLabel::setPixmap(const QPixmap& pixmap) {
    setDefaultPixmap(pixmap);
}

// 获取当前显示的Pixmap（根据当前状态，未设置时自动使用default的pixmap）
QPixmap ClickableLabel::getCurrentPixmap() const {
    switch (m_currentState) {
    case State::Hovered:
        return m_hoveredPixmap.isNull() ? m_defaultPixmap : m_hoveredPixmap;
    case State::Pressed:
        return m_pressedPixmap.isNull() ? m_defaultPixmap : m_pressedPixmap;
    case State::Selected:
        return m_selectedPixmap.isNull() ? m_defaultPixmap : m_selectedPixmap;
    default: // State::Default
        return m_defaultPixmap;
    }
}

// 颜色设置相关方法
void ClickableLabel::setDefaultColor(const QColor& color) {
    m_defaultColor = color;
    if (m_currentState == State::Default) {
        update();
    }
}

QColor ClickableLabel::getDefaultColor() const {
    return m_defaultColor;
}

void ClickableLabel::setPressedColor(const QColor& color) {
    m_pressedColor = color;
    if (m_currentState == State::Pressed) {
        update();
    }
}

QColor ClickableLabel::getPressedColor() const {
    return m_pressedColor;
}

void ClickableLabel::setHoverColor(const QColor& color) {
    m_hoverColor = color;
    if (m_currentState == State::Hovered) {
        update();
    }
}

QColor ClickableLabel::getHoverColor() const {
    return m_hoverColor;
}

// 形状设置相关方法
void ClickableLabel::setShape(Shape shape) {
    m_shape = shape;
    updateGeometry();
    update();
}

void ClickableLabel::setBorderRadius(int radius) {
    m_borderRadius = radius;
    if (m_shape == Shape::Rectangle) {
        updateGeometry();
        update();
    }
}

void ClickableLabel::setRadius(int radius) {
    m_radius = radius;
    if (m_shape == Shape::Circle) {
        updateGeometry();
        update();
    }
}

// 边距设置相关方法
void ClickableLabel::setMargins(int left, int top, int right, int bottom) {
    m_margins = QMargins(left, top, right, bottom);
    updateGeometry();
    update();
}

void ClickableLabel::setMargins(const QMargins& margins) {
    m_margins = margins;
    updateGeometry();
    update();
}

QMargins ClickableLabel::getMargins() const {
    return m_margins;
}

// 间距和对齐设置相关方法
void ClickableLabel::setPixmapTextSpacing(int spacing) {
    m_pixmapTextSpacing = spacing;
    updateGeometry();
    update();
}

int ClickableLabel::getPixmapTextSpacing() const {
    return m_pixmapTextSpacing;
}

void ClickableLabel::setContentAlignment(ContentAlignment alignment) {
    m_alignment = alignment;
    update();
}

ClickableLabel::ContentAlignment ClickableLabel::getContentAlignment() const {
    return m_alignment;
}

// 文本颜色设置
void ClickableLabel::setTextColor(const QColor& color) {
    m_textColor = color;
    update();
}

QColor ClickableLabel::getTextColor() const {
    return m_textColor;
}

// 鼠标事件处理（根据模式有不同行为）
void ClickableLabel::mouseMoveEvent(QMouseEvent* event) {
    bool inShape = isPointInShape(event->pos());
    State newState = m_currentState;

    if (m_mode == Mode::Button) {
        // 按钮型模式
        if (inShape) {
            newState = (m_currentState == State::Pressed) ? State::Pressed : State::Hovered;
        } else {
            newState = State::Default;
        }
    } else {
        // 选择型模式
        if (inShape && !m_selected) {
            // 未选中时才有悬停效果
            newState = (m_currentState == State::Pressed) ? State::Pressed : State::Hovered;
        } else if (!inShape && !m_selected) {
            newState = State::Default;
        }
        // 选中状态不随鼠标移动改变
    }

    if (newState != m_currentState) {
        m_currentState = newState;
        update();
    }
    QLabel::mouseMoveEvent(event);
}

void ClickableLabel::enterEvent(QEnterEvent* event) {
    State newState = m_currentState;

    if (m_mode == Mode::Button) {
        // 按钮型：进入时变为悬停状态（除非正在按下）
        newState = (m_currentState == State::Pressed) ? State::Pressed : State::Hovered;
    } else {
        // 选择型：未选中时才有悬停效果
        if (!m_selected && m_currentState != State::Pressed) {
            newState = State::Hovered;
        }
    }

    if (newState != m_currentState) {
        m_currentState = newState;
        update();
    }
    QLabel::enterEvent(event);
}

void ClickableLabel::leaveEvent(QEvent* event) {
    State newState = m_currentState;

    if (m_mode == Mode::Button) {
        // 按钮型：离开时恢复默认状态
        newState = State::Default;
    } else {
        // 选择型：未选中时恢复默认状态
        if (!m_selected) {
            newState = State::Default;
        }
    }

    if (newState != m_currentState) {
        m_currentState = newState;
        update();
    }
    QLabel::leaveEvent(event);
}

void ClickableLabel::mousePressEvent(QMouseEvent* event) {
    if (isPointInShape(event->pos())) {
        m_currentState = State::Pressed;
        update();
    }
    QLabel::mousePressEvent(event);
}

void ClickableLabel::mouseReleaseEvent(QMouseEvent* event) {
    bool inShape = isPointInShape(event->pos());
    if (m_currentState == State::Pressed) {
        if (inShape) {
            emit clicked();  // 只触发信号，让外部处理选中逻辑

            if (m_mode == Mode::Button) {
                m_currentState = State::Hovered;
            } else if (m_mode == Mode::Selectable) {
                // 只有 Selectable 模式才自动切换
                setSelected(!m_selected);
            }
            // ExclusiveSelectable 模式：不做任何自动切换
        } else {
            // 鼠标释放时不在控件上，恢复状态
            if (m_mode == Mode::Button) {
                m_currentState = State::Default;
            } else if (!m_selected) {
                m_currentState = State::Default;
            }
        }
        update();
    }
    QLabel::mouseReleaseEvent(event);
}

// 重绘事件
void ClickableLabel::paintEvent(QPaintEvent* event) {
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setPen(Qt::NoPen);

    // 根据当前状态设置背景色
    switch (m_currentState) {
    case State::Pressed:
        painter.setBrush(m_pressedColor);
        break;
    case State::Hovered:
        painter.setBrush(m_hoverColor);
        break;
    case State::Selected:
        painter.setBrush(m_selectedColor);
        break;
    default: // State::Default
        painter.setBrush(m_defaultColor);
        break;
    }

    // 获取当前状态的Pixmap（为空时fallback到默认）
    QPixmap currentPix = getCurrentPixmap();

    // 根据形状绘制
    switch (m_shape) {
    case Shape::Rectangle:
        ShapeDrawer<Shape::Rectangle>::draw(painter, rect(), m_borderRadius,
                                            text(), m_textColor, currentPix,
                                            m_pixmapTextSpacing, m_margins, m_alignment);
        break;
    case Shape::Circle:
        ShapeDrawer<Shape::Circle>::draw(painter, rect(), m_radius,
                                         text(), m_textColor, currentPix,
                                         m_pixmapTextSpacing, m_margins, m_alignment);
        break;
    }
}

// 最小尺寸计算
QSize ClickableLabel::minimumSizeHint() const {
    // 1. 计算内容本身的最小尺寸（文字+当前Pixmap+间距）
    QFontMetrics fontMetrics = this->fontMetrics();
    QSize contentSize = calculateContentMinimumSize(
        fontMetrics, m_currentState, m_pixmapTextSpacing, m_alignment
        );

    // 2. 加上边距和边框
    int totalWidth = contentSize.width() + m_margins.left() + m_margins.right() + 2;
    int totalHeight = contentSize.height() + m_margins.top() + m_margins.bottom() + 2;

    // 3. 根据形状调整最小尺寸
    switch (m_shape) {
    case Shape::Rectangle:
        totalWidth = qMax(totalWidth, 2 * m_borderRadius);
        totalHeight = qMax(totalHeight, 2 * m_borderRadius);
        break;
    case Shape::Circle:
        int minCircleSize = 2 * m_radius + 2;
        totalWidth = qMax(totalWidth, minCircleSize);
        totalHeight = qMax(totalHeight, minCircleSize);
        totalWidth = totalHeight = qMax(totalWidth, totalHeight);
        break;
    }

    // 4. 避免零尺寸
    const int minDefaultSize = 10;
    totalWidth = qMax(totalWidth, minDefaultSize);
    totalHeight = qMax(totalHeight, minDefaultSize);

    return QSize(totalWidth, totalHeight);
}

// 内容最小尺寸计算
QSize ClickableLabel::calculateContentMinimumSize(const QFontMetrics& fontMetrics,
                                                  State currentState,
                                                  int spacing,
                                                  ContentAlignment alignment) const {
    int textWidth = fontMetrics.horizontalAdvance(text());
    int textHeight = fontMetrics.height();

    // 根据当前状态获取Pixmap尺寸，未设置时使用default的
    QPixmap currentPix;
    switch (currentState) {
    case State::Hovered:
        currentPix = m_hoveredPixmap.isNull() ? m_defaultPixmap : m_hoveredPixmap;
        break;
    case State::Pressed:
        currentPix = m_pressedPixmap.isNull() ? m_defaultPixmap : m_pressedPixmap;
        break;
    case State::Selected:
        currentPix = m_selectedPixmap.isNull() ? m_defaultPixmap : m_selectedPixmap;
        break;
    default:
        currentPix = m_defaultPixmap;
        break;
    }

    int pixmapWidth = currentPix.width();
    int pixmapHeight = currentPix.height();

    bool hasPixmap = !currentPix.isNull();
    bool hasText = !text().isEmpty();

    if (hasPixmap && hasText) {
        if (alignment == ContentAlignment::Left || alignment == ContentAlignment::Right) {
            return QSize(pixmapWidth + textWidth + spacing, qMax(pixmapHeight, textHeight));
        } else {
            return QSize(qMax(pixmapWidth, textWidth), pixmapHeight + textHeight + spacing);
        }
    } else if (hasPixmap) {
        return currentPix.size();
    } else if (hasText) {
        return QSize(textWidth, textHeight);
    } else {
        return QSize(0, 0);
    }
}

// 形状内点判断
bool ClickableLabel::isPointInShape(const QPoint& point) const {
    switch (m_shape) {
    case Shape::Rectangle:
        return ShapeDrawer<Shape::Rectangle>::contains(rect(), m_borderRadius, point);
    case Shape::Circle:
        return ShapeDrawer<Shape::Circle>::contains(rect(), m_radius, point);
    default:
        return false;
    }
}
